/*******************************************************************************
 * Witz - Winboard Chess Engine                                                *
 * DEFS.H                                                                      *
 *                                                                             *
 * Consists of type declarations, constants, macros, and assembler routines    *
 * required throught the program.                                              *
 *                                                                             *
 * Please refer to the licence notice in MAIN.C                                *
 *                                                                             *
 * Copywright (C) 2006 Pradu Kannan                                            *
 * http://witz.sf.net/                                                         *
 ******************************************************************************/

#ifndef __defs
#define __defs

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/timeb.h>
#include <time.h>
#include <math.h>
#include <ctype.h>
//#include <pthread.h>

/******************************BASIC DEFENITIONS*******************************/
//define boolean types and constants
typedef char	bool;
#define true	1
#define false   0

//defining unsigned integer types
typedef unsigned long long  U64; /*also works with MSVC 2003 or greater*/
typedef unsigned int        U32;
typedef unsigned short      U16;
typedef unsigned char       U8;

//defining Infinity, Negative infinity, and mate
#define INF          2147400000
#define NEGINF       -INF
#define MATE         2147399000

//defining full and empty U64 numbers
#define U64FULL     0xFFFFFFFFFFFFFFFFULL
#define U64EMPTY    0x0000000000000000ULL

/*****************************SIZE DECLARATIONS********************************/

#define	MAX_PLY             1024
#define	MAX_GAMELENGTH      1024
#define	MAX_MOVECHOICES     256

/*****************************BOARD DEFENITIONS********************************/

//Color/Side Defenitions
#define WHITE  0
#define BLACK  1
#define NOSIDE 2

//Piece defenitions in order of relative value
#define EMPTY   0 //empty
#define P       1 //pawn
#define N       2 //knight
#define B       3 //bishop
#define R       4 //rook
#define Q       5 //queen
#define K       6 //king

//defines the number of piece types
#define NUMPIECETYPES 7

//defines the game results for a certain side
#define LOSS 0
#define DRAW 1
#define WIN  2

//A move
typedef U32 move;

/*********************Format of a Move**************************
A move is stored in 23 bits:
Bits    (6)	0-5     are for the "to square".
Bits    (3)	6-8     are for the "capture piece".
Bits    (3)	9-11    are for the "moving piece".
Bits    (6)	12-17   are for the "from square".
Bits    (3)	18-20   are for the "promoting piece".
Bit     (1)	21      is for identifying "enpassant" or "castling"
Bit	   (1)	22      is for identifying "kingside" or "queenside"
****************************************************************/

//A null move
#define NULLMOVE 0

//macros to help encode data X into a move
#define encodeTo(X)         (X)
#define encodeCapture(X)    ((X)<<6)
#define encodePiece(X)      ((X)<<9)
#define encodeFrom(X)       ((X)<<12)
#define encodePromotion(X)  ((X)<<18)
#define encodeSpecial(X)    ((X)<<21)

//macros to help extract data from move X
#define extractTo(X)		((X)&0x3F)
#define extractCapture(X)	(((X)>>6)&7)
#define extractPiece(X)		(((X)>>9)&7)
#define extractFrom(X)		(((X)>>12)&0x3F)
#define extractPromotion(X)	(((X)>>18)&7)
#define extractSpecial(X)	((X)>>21)

//special bits for the move
#define encodeEP                   0x200000
#define encodeKingsideCastle       0x200000
#define encodeQueensideCastle      0x400000

//a scored move
typedef struct _smove
{
	move m;
	int score;
}smove;

//a move list
typedef struct _moveList
{
	smove moves[MAX_MOVECHOICES];
	short moveCount;
}moveList;

//the board structure
typedef struct _board
{
	U64   AllPieces;             //All the pieces on the board
	U64   R45;                   //All the pieces rotated 45 degrees right
	U64   L45;                   //All the pieces rotated 45 degrees left
	U64   L90;                   //All the pieces rotated
	U64   PiecesSide[2];         //All the pieces belonging to each side
	U64   Pieces[NUMPIECETYPES]; //Specific pieces on the board eg Pieces[N]
	U64   EP;                    //Any enpassant squares
	U64   hashkey;               //the hash key for the transposition table
	int   material;              //the material balence for the current position
	U8    PieceTypes[64];        //All the piece types according to squares
	U8    castling;              //Castling privilages - format defined below
	U8    fifty;                 //Fifty move count
	U8    SF;                    //Search Flags (see Search Related section)
	bool  side;                  //the side to play
	bool  xside;                 //the side opposite to play
}board;

/*******************Castling Format*********************************************
 *(White KingSide) (White QueenSide) (Black KingSide) (Black QueenSide)
 *If black can castle on both sides and white can castle only on kingside, then
 *the number would be 0111 in binary.
 *
 *BK - Black Kingside
 *BQ - Black Queenside
 *WK - White Kingside
 *WQ - White Queenside
 ******************************************************************************/

//defining Kingside and Queenside
#define KINGSIDE	0
#define QUEENSIDE	1

//castlings
#define WK 1 // 0001
#define WQ 2 // 0010
#define BK 4 // 0100
#define BQ 8 // 1000

//castlings for each side
#define BCASTLE	0xC	//(1100)
#define WCASTLE	0x3	//(0011)

//some defines for castling privilages
#define hasCastlingPrivilages(pos,side)  (((pos).castling>>castlingPrivilageShift[side])&3)
#define canCastleSide(pos,castlingSide)  ((hasCastlingPrivilages&(pos,1<castlingSide)) && !(((pos).AllPieces>>castlingShift[(pos).side])&castlingAnds[castlingSide]))

//finding the column and row number of a square
#define COL(X) ((X)%8)
#define ROW(X) ((X)/8)

//tells you whether two squares are diaognal or not
#define isDiagonal(i,j) (ROW(i)!=ROW(j) && COL(i)!=COL(j))

//white and black squares
#define WHITESQUARES 0x55AA55AA55AA55AAULL
#define BLACKSQUARES 0xAA55AA55AA55AA55ULL

/********************************EVALUATION************************************/

//Piece Values
#define default_Pval		100     //pawn value
#define default_Nval		325     //knight value
#define default_Bval		325     //bishop value
#define default_Rval		500     //rook value
#define default_Qval		900     //queen value
#define default_Kval		8000    //king value

#define EMPTYval      0       //empty value

//mobility weights
#define default_MOB_WEIGHT    2
#define default_CAPTURE_BONUS 1

//king safety weight
#define default_KS_WEIGHT     3

#define default_KS_ScaleStart 2300
#define default_KS_ScaleEnd   825

/*****************************BITBOARD SPECIFIC********************************/

//FirstOne and LastOne instructions
#define FirstOne(X) Log2((X) & ((U64)(-((signed long long)X))))
#define LastOne(X)  Log2(X)

//for the following pos isn't treated as a board pointer but instead the board itself

//Finding occupancy for sliding pieces
#define occupancya1h8(pos,X)	(((pos).R45>>a1h8shift[X]) & 0xFF)
#define occupancyh1a8(pos,X)	(((pos).L45>>h1a8shift[X]) & 0xFF)
#define occupancyrank(pos,X)	(((pos).AllPieces>>rankshift[X]) & 0xFF)
#define occupancyfile(pos,X)	(((pos).L90>>fileshift[X]) & 0xFF)

//Moves of sliding pieces on square X (parameters are kept the same so that it might make code more readable)
#define Bmoves(pos,X) ((a1h8moves[(X)][occupancya1h8(pos,X)])|(h1a8moves[(X)][occupancyh1a8(pos,X)]))
#define Rmoves(pos,X) ((rankmoves[(X)][occupancyrank(pos,X)])|(filemoves[(X)][occupancyfile(pos,X)]))
#define Qmoves(pos,X) (Bmoves(pos,X)|Rmoves(pos,X))
#define Nmoves(pos,X) (Nmoves[X])
#define Kmoves(pos,X) (Kmoves[X])
//Pmoves(pos,X) is a function in movegen.h and pos is a board pointer instead

//Getting Pieces of a certain side
#define piecesSide(pos,piece)   ((pos).Pieces[(piece)]&(pos).PiecesSide[(pos).side])
#define piecesXSide(pos,piece)  ((pos).Pieces[(piece)]&(pos).PiecesSide[(pos).xside])
#define piecesWHITE(pos,piece)   ((pos).Pieces[(piece)]&(pos).PiecesSide[WHITE])
#define piecesBLACK(pos,piece)   ((pos).Pieces[(piece)]&(pos).PiecesSide[BLACK])

//getting the attacksTo and attacksFrom bitmaps
#define attacksTo(pos,X)	((Bmoves(pos,X)& ((pos).Pieces[B]|(pos).Pieces[Q]))|(Rmoves(pos,X)& ((pos).Pieces[R]|(pos).Pieces[Q]))|(Nmoves[X]&(pos).Pieces[N])|(Kmoves[X]&(pos).Pieces[K])|(Pcaps[WHITE][X]&((pos).Pieces[P]&(pos).PiecesSide[BLACK]))|(Pcaps[BLACK][X]&((pos).Pieces[P]&(pos).PiecesSide[WHITE])))

//returns whether the side is attacked at the square - also retruns locatin of all attackers
#define isAttacked(pos,square,side) (attacksTo(pos,square)& (pos).PiecesSide[!side])

//returns whether the side is in check
#define inCheck(pos,side) isAttacked(pos,LastOne(((pos).Pieces[K]&(pos).PiecesSide[side])),side)

/******************************SEARCH RELATED**********************************/

#define INITIAL_DEPTH_LIMIT 7
#define QS_FUTIL_MARGIN     Pval

#define INITIAL_STI 3

//used to detect 3 move repetition draws
typedef struct _drawEntry
{
	U64 hashkey;     //hash key for the position
	bool fiftyReset; //is the move a capture or a pawn move
}drawEntry;

//SearchFlags are of type U8
/*******************Format of a Search Flag*********************
Bits    (3)	0-2		piece captured by move to the parent node
Bit     (1)	3		nullmove was just made in search
Bit     (1) 4       do not do verified nullmove
****************************************************************/

//defines to encode a searchFlag
#define encodeSFRecapture(PIECE)   (PIECE)
#define encodeSFNull               0x8
#define encodeSFNoVerify           0x10

//defines to extract from a searchFlag
#define extractSFRecapture(SF)     (SF&0x7)
#define extractSFNull(SF)          (SF&encodeSFNull)
#define extractSFNoVerify(SF)      (SF&encodeSFNoVerify)

//clear search flags
#define clearSearchFlags(SF)       (SF)&=encodeSFNoVerify

//search types
#define PVS 0 /*Principal Variation Search*/
#define AB  1 /*AlphaBeta*/

#define default_searchType AB

//divides the timeleft by the following number
#define TIME_DIVIDER 35

/***************************MOVE ORDERING RELATED******************************/

#define CASTLING_BONUS 10
#define ORDERING_CAPTURE_BONUS   5

//max HH value
#ifdef SEEVAL
#undef SEEVAL
#endif
#define SEEVAL     2147391000

//Killer value
#define KILLERVAL    2147390000

//Transposition Table

//Transposition table entry (18 bytes used)
/*Since this is 8bit aligned, the actual size is 24 bytes*
 *I will find a use for the other 6 used bytes later     */
typedef struct _TTentry
{
	U64 key;     //the hash key for the position
	/*data
	 Bits    (23)   0-22    are for move data
	 Bits    (2)    22-24   are for the hash flag
	 Bits    (9)    24-31   are for the depth
	*/
	U32 data;
	int score; //the score for the position
	U16 age;     //the age (in plys) in the game when the entry was created
}TTentry;

//A transposition table structure used when probing the TT
typedef struct _TTprobe
{
	move m;      //the best move
	int score;  //the tt score
	short depth; //depth of the entry
	char  flag;   //hash flag
}TTprobe;

//macros to encode data to the data part of TTentry
#define encodeMove(X)   (X)
#define encodeFlag(X)   ((X)<<23)
#define encodeDepth(X)  ((X)<<25)

//macros to extract data from the data part of TTentry
#define extractMove(X)  ((X)&0x7FFFFF)
#define extractFlag(X)  (((X)>>23)&0x3)
#define extractDepth(X) ((U16)((X)>>25))

//flag defines
#define EXACT 0
#define ALPHA 1
#define BETA  2

/****************************WINBOARD DEFINITIONS******************************/

//Recognized message flags

//Null flag
#define MF_NULL		0 /*continue with search*/

/*Board changing command
 *move,white,black,setboard,edit,new
 *Response: Quit search wihtout updating the board
 */
#define MF_BOARDCHANGE	1

/*Move Now Command
 *?, time's up
 *Response: Quit search and play best move
 */
#define MF_MOVE		2

/*Side Change Command/Ponder commands
 *force,go,playother,analyze,(hard,easy),result
 *Response: Quit search and make no move
 */
#define MF_NOMOVE	3 /*quit the search and make no move*/

//charecter defines for printBoard()

//corners
#define PB_UL	218	//upper left corner
#define PB_UR	191	//upper right corner
#define PB_LL	192	//lower left corner
#define PB_LR	217	//lower right corner

//sides and intersections
#define PB_H	196	//horizontal piece
#define PB_V	179	//vertical piece
#define PB_HD	194	//horizontal down
#define PB_HU	193	//horizontal up
#define PB_VR	195	//vertical right
#define PB_VL	180	//vertical left
#define PB_CRS	197	//cross

/***********************************BOOK***************************************/

//a book position (16 bytes)
typedef struct _bookPosition
{
	U64 key;      //the position's key
	U32 numGames; //the 2x number of games where the current position occurs
	U32 results;  //the number of times the side not on move wins
	              //no points for lost games
	              //one point is added for drawn games
	              //two points are added for won games
}bookPosition;

//a data that can be used to make book from pgn files
typedef struct _pgnPosition
{
	U64 key;    //the position's key
	int result; //the position's result
	            //no points for loss
	            //one point for draw
	            //two points for wins
}pgnPosition;

//a pgn file with all the data about its current state
typedef struct _pgnFile
{
	FILE* pointer;   //pointer to the ASCII file
	int stage;       //see stage defenitions below
	board pos;       //the board position for the game being read
	int game;        //the game number
	int ply;         //the ply of the game being read
	char line[512];  //what's left of the line being read in the current game
}pgnFile;

//defenition of pgn file stages
#define PGN_STAGE_SEARCH 0 /*searching the pgn file for a game*/
#define PGN_STAGE_BLACK  1 /*the game being read is won by black*/
#define PGN_STAGE_WHITE  2 /*the game being read is drawn*/
#define PGN_STAGE_DRAW   3 /*the game being read is won by white*/

//defines for the red-black trees for creating the book
typedef struct _rbNode
{
	bookPosition bookPos;   //the book position data
	struct _rbNode* left;   //nodes with a key less than the current node
	struct _rbNode* right;  //nodes with a key greater than the current node
	struct _rbNode* parent; //the parent node
	bool color;             //the color, either red or black
}rbNode;

//BLACK is already define, define RED
#define RED WHITE

//some macros used in the insertion code
#define grandparent(n) ((n)->parent->parent)
#define uncle(n) (((n)->parent==grandparent(n)->left)?grandparent(n)->right:grandparent(n)->left)

//gets the key of a red-black node
#define rbkey(n) ((n)->bookPos.key)

/***************************CONFIGURATION FILE*********************************/
//default values

#define default_configPath "config.ini"

//transposition table Size
#define default_TT_SIZE 6 //64 MB

//path types
#define PATH_RELATIVE 0
#define PATH_ABSOLUTE 1

//book location
#define default_hasBook   1
#define default_bookPath  "Books/Olivier_GM2001.book"
#define default_bookPathType PATH_RELATIVE
#define default_gamesWeight 1 /*100%*/
#define default_winsWeight 0

//search
#define default_checkEvasions false
#define default_recaptureExtensions true

#define NULLMOVE_TYPE_ADAPTIVE false

#define default_nullMoveType NULLMOVE_TYPE_ADAPTIVE

//Principal Variation Print Time when playing in ICS
#define default_ICS_PV .9

//additional values found in evaluvation and search sections

#endif
